﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NUnit.Framework;
using SistemaDeBastanteodePoderes.Persistencia;
using SistemaDeBastanteodePoderes.Dominio;

namespace SistemaDeBastanteodePoderes.Pruebas.DAO
{
    [TestFixture]
    public class Test_H3_2_PoderDAO
    {
        ITipoServicioDAO tipoServicioDAO = null;
        IPoderDAO poderDAO = null;
        TipoServicio tipoServicio = null;
        Poder poderCreado = null;

        [TestFixtureSetUp]
        public void InicializarPruebas()
        {
            tipoServicioDAO = new Persistencia.NH.TipoServicioDAO(); // NHibernate
            poderDAO = new Persistencia.NH.PoderDAO(); // NHibernate
            foreach (Poder poder in poderDAO.ListarTodos())
                poderDAO.Eliminar(poder);
            tipoServicio = tipoServicioDAO.Crear(new TipoServicio() { Servicio = "ACTIVO" });
        }

        [Test]
        public void Test1_Crear()
        {
            // 1. Validar que ocurra un error al intentar crear un PODER con un dato nulo
            Poder poderACrear = new Poder();
            poderACrear.CodCorto = "POD01";
            poderACrear.NomPoder = "PODER 01";
            poderACrear.Servicio = null;
            Assert.Catch<Exception>(delegate
            {
                poderCreado = poderDAO.Crear(poderACrear);
            });

            // 2. Validar que se cree un PODER correctamente (sin error)
            poderACrear.Servicio = tipoServicio;
            Assert.DoesNotThrow(delegate
            {
                poderCreado = poderDAO.Crear(poderACrear);
            });

            // 3. Validar que el PODER creado no sea nulo, tenga un código mayor a 0 y el servicio sea el ingresado
            Assert.IsNotNull(poderCreado);
            Assert.Greater(poderCreado.Codigo, 0);
            Assert.AreEqual(poderCreado.Servicio.Codigo, tipoServicio.Codigo);
        }
        [Test]
        public void Test2_Obtener()
        {
            Poder poderObtenido = null;

            // 1. Validar que se retorne nulo al obtener un PODER inexistente
            Assert.DoesNotThrow(delegate
            {
                poderObtenido = poderDAO.Obtener(1000);
            });
            Assert.IsNull(poderObtenido);

            // 2. Validar que se obtenga el PODER creado satisfactoriamente
            Assert.DoesNotThrow(delegate
            {
                poderObtenido = poderDAO.Obtener(poderCreado.Codigo);
            });
            Assert.IsNotNull(poderObtenido);

            // 3. Validar que el poder obtenido sea el creado anteriormente
            Assert.AreEqual(poderObtenido.Codigo, poderCreado.Codigo);
        }
        [Test]
        public void Test3_Modificar()
        {
            Poder poderAModificar = poderDAO.Obtener(poderCreado.Codigo);
            poderAModificar.CodCorto = "POD99";
            poderAModificar.NomPoder = "PODER 99";
            poderAModificar.Servicio = null;
            Poder poderModificado = null;

            // 1. Validar que ocurrar un error al intentar modificar el PODER con un SERVICIO nulo
            Assert.Catch<Exception>(delegate
            {
                poderModificado = poderDAO.Modificar(poderAModificar);
            });

            // 2. Validar que se modifique correctamente el PODER
            poderAModificar.Servicio = tipoServicio;
            Assert.DoesNotThrow(delegate
            {
                poderModificado = poderDAO.Modificar(poderAModificar);
            });
            // 3. Validar que el cliente modificado no sea nulo, tenga la razón social, número de empleados y tipo indicados
            Assert.IsNotNull(poderModificado);
            Assert.AreEqual(poderAModificar.CodCorto, poderModificado.CodCorto);
            Assert.AreEqual(poderAModificar.NomPoder, poderModificado.NomPoder);
            Assert.AreEqual(poderAModificar.Servicio.Codigo, poderModificado.Servicio.Codigo);
        }
        [Test]
        public void Test4_Eliminar()
        {
            Poder poderAEliminar = poderDAO.Obtener(poderCreado.Codigo);

            // 1. Validar que ocurre un error si se intenta eliminar un PODER nulo
            Assert.Catch<Exception>(delegate
            {
                poderDAO.Eliminar(null);
            });

            // 2. Validar que se elimina correctamente el PODER creado
            Assert.DoesNotThrow(delegate
            {
                poderDAO.Eliminar(poderAEliminar);
            });

            // 3. Validar que luego de eliminado se retorne nulo al obtenerlo
            Poder poderEliminado = poderDAO.Obtener(poderCreado.Codigo);
            Assert.IsNull(poderEliminado);

        }
        [Test]
        public void Test5_Listar()
        {
            poderDAO.Crear(new Poder() { CodCorto = "POD6", NomPoder = "PODER 6", Servicio = tipoServicio});
            poderDAO.Crear(new Poder() { CodCorto = "POD7", NomPoder = "PODER 7", Servicio = tipoServicio });

            // 1. Validar que se listen los PODERES existentes exitosamente
            ICollection<Poder> poderesExistentes = null;
            Assert.DoesNotThrow(delegate
            {
                poderesExistentes = poderDAO.ListarTodos();
            });

            // 2. Validar que se retornen al menos los 2 PODERES creados previamente
            Assert.GreaterOrEqual(poderesExistentes.Count, 2);

            // 3. Validar que cada PODER obtenido tenga un Codigo corto no nulo
            foreach (Poder poder in poderesExistentes)
                Assert.IsNotNull(poder.CodCorto);
        }

        [TestFixtureTearDown]
        public void FinalizarPruebas()
        {
            foreach (Poder poder in poderDAO.ListarTodos())
                poderDAO.Eliminar(poder);
            tipoServicioDAO.Eliminar(tipoServicio);
            Persistencia.NH.NHibernateHelper.CerrarFabrica();
        }
    }
}